package com.sky.aspect;

import com.sky.anotation.AutoFill;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.time.LocalDateTime;

/**
 * 定义自动填充切面
 * 增强目标1方法的类
 */
@Aspect
@Component
@Slf4j
public class AutoFillAspect {
/**
 * 定义切入点
 */
@Pointcut("execution(* com.sky.mapper.*.*(..))&&@annotation(com.sky.anotation.AutoFill)")
public void autoFillPointCut(){

}

/**
 * 定义前置通知（在通知中，写反射代码吗，实现自动填充
 */
@Before("autoFillPointCut()")
public void autoFill(JoinPoint joinPoint){
    log.info("开始进行自动填充...");
    Object[] args=joinPoint.getArgs();
    if (args==null||args.length==0){
        return;
    }
    try {
        // 获取目标方法中的参数（Employee Category  Dish）
        Object object = args[0];
        //方法签名
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //获取方法 void insert(Employee employee);
        Method method = signature.getMethod();
        //获取方法上的注解 @AutoFill(value = OperationType.INSERT)
        AutoFill autoFill = method.getAnnotation(AutoFill.class);
        //获取注解上的值
        OperationType operationType = autoFill.value();
        //我要反射填充4个字段 createTime,createUser ,updateTime,updateUser
        Class<?> clazz = object.getClass();
        //获取字节中的setUpdateTime方法
        Method setUpdateTime = clazz.getMethod("setUpdateTime", LocalDateTime.class);
        //调用setUpdateTime方法填充值
        setUpdateTime.invoke(object, LocalDateTime.now());
        //获取字节中的setUpdateUser方法
        Method setUpdateUser = clazz.getMethod("setUpdateUser", Long.class);
        //调用setUpdateUser方法填充值
        setUpdateUser.invoke(object, BaseContext.getCurrentId());
        //判断对数据库的操作是不是Insert
        if(operationType==OperationType.INSERT){
            //获取字节中的setCreateTime方法
            Method setCreateTime = clazz.getMethod("setCreateTime", LocalDateTime.class);
            //调用setCreateTime方法填充值
            setCreateTime.invoke(object, LocalDateTime.now());

            //获取字节中的setCreateUser方法
            Method setCreateUser = clazz.getMethod("setCreateUser",Long.class);
            //调用setCreateUser方法填充值
            setCreateUser.invoke(object, BaseContext.getCurrentId());
        }
    }catch (Exception e){
        log.error("自动填充失败：{}",e.getMessage());
    }



}
}
